package leetcode.lt100;

class Solution_82 {

    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.append(2).append(2).append(3).append(4).append(4).append(5);
        System.out.println(deleteDuplicates3(head));
        System.out.println(deleteDuplicates2(head));
        System.out.println(deleteDuplicates(head));
    }

    public static ListNode deleteDuplicates(ListNode head) {
        //baseCase
        if (head == null || head.next == null) {
            return head;
        }

        ListNode next = head.next;
        //如果是这种情况
        //      1 --> 1 --> 1 --> 2 --> 3
        //     head  next
        //1.则需要移动next直到出现与当前head.value不相等的情况（含null）
        //2.并且此时的head已经不能要了，因为已经head是重复的节点
        //--------------else-------------
        //      1 --> 2 --> 3
        //     head  next
        //3.如果没有出现1的情况，则递归返回的节点就作为head的子节点
        if (head.val == next.val) {
            //1
            while (next != null && head.val == next.val) {
                next = next.next;
            }
            //2
            head = deleteDuplicates(next);
        } else {
            //3
            head.next = deleteDuplicates(next);
        }
        return head;
    }

    public static ListNode deleteDuplicates2(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        ListNode slow = dummy.next;
        ListNode fast = dummy.next.next;
        while (fast != null) {
            if (slow.val == fast.val)
                fast = fast.next;
            else {
                if (slow.next != fast) {
                    ListNode fastRecord = fast;
                    fast = fast.next;
                    slow = fastRecord;
                    prev.next = slow;
                } else {
                    fast = fast.next;
                    slow = slow.next;
                    prev = prev.next;
                }
            }
        }
        if (slow.next != null) {
            prev.next = null;
        }
        return dummy.next;
    }

    public static ListNode deleteDuplicates3(ListNode head) {
        ListNode dummy = new ListNode(0);
        ListNode preNode = null;
        ListNode currentNode = head;

        ListNode lastNode = dummy;
        while (currentNode != null) {
            if (isNotDuplicates(currentNode, preNode)) {
                lastNode.next = new ListNode(currentNode.val);
                lastNode = lastNode.next;
            }
            preNode = currentNode;
            currentNode = currentNode.next;
        }
        return dummy.next;
    }

    private static boolean isNotDuplicates(ListNode currentNode, ListNode preNode) {
        if (preNode != null && currentNode.val == preNode.val) {
            return false;
        }
        if (currentNode.next != null && currentNode.val == currentNode.next.val) {
            return false;
        }
        return true;
    }

    /**
     * Definition for singly-linked list.
     **/
    static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }

        @Override
        public String toString() {
            if (next == null) {
                return val + "";
            } else {
                return val + "," + next.toString();
            }
        }

        public ListNode append(int val) {
            next = new ListNode(val);
            return next;
        }
    }

}